package net.xumf.web.controller.login;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.xumf.domain.master.SystemUser;
import net.xumf.service.master.SystemUserService;
import net.xumf.support.auth.JWTUtil;
import net.xumf.support.consts.Constants;
import net.xumf.support.model.ResponseResult;
import net.xumf.support.model.dto.LoginDTO;
import net.xumf.support.model.dto.RegisterDTO;
import net.xumf.support.security.PasswordService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

@Slf4j
@Controller
@Api(value = "登录", description = "登录与跳转首页")
public class LoginController {


    @Autowired
    private SystemUserService systemUserService;

    @ApiOperation(value = "首页", notes = "跳转到首页")
    @RequestMapping({"/", "home"})
    public String index() {
        return "index";
    }

    @ApiOperation(value = "登录页面")
    @GetMapping("/login")
    public ModelAndView loginPage() {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("login");
        return mav;
    }

    @ApiOperation(value = "登录操作", notes = "用户通过输入login name 与 password登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginName", value = "登录名", required = true, dataTypeClass = String.class, paramType = "queryer", example = "admin"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataTypeClass = String.class, paramType = "queryer", example = "123456"),
            @ApiImplicitParam(name = "rememberMe", value = "记住我", required = true, dataTypeClass = Boolean.class, paramType = "queryer", example = "true"),
    })
    @PostMapping("/login/action")
    @ResponseBody
    public ResponseResult loginAction(@Valid LoginDTO loginDTO, BindingResult result, HttpServletResponse response) throws Exception {

        if (result.hasErrors()) {
            FieldError fieldError = result.getFieldError();
            return ResponseResult.failure(fieldError.getDefaultMessage());
        }
        String afterDecryptionPassword = PasswordService.decryptAesPassword(loginDTO.getPassword(), Constants.Normal.PASSWORD_KEY);
        loginDTO.setPassword(afterDecryptionPassword);
        // 登录
        SystemUser user = systemUserService.login(loginDTO);
        JWTUtil.sign(user.getLoginName(), user.getSalt().toString(), Constants.Normal.TOKEN_VALID_TIME).ifPresent(o -> {
            Cookie cookie = new Cookie(Constants.Normal.TOKEN_NAME, o);
            cookie.setHttpOnly(true);
            cookie.setMaxAge(Constants.Normal.TOKEN_VALID_TIME);
            cookie.setPath("/");
            response.addCookie(cookie);
        });
        return ResponseResult.success();
    }

    @ApiOperation(value = "登出")
    @PostMapping("/logout")
    @ResponseBody
    public ResponseResult logout(HttpServletResponse res) {
        Cookie cookie = new Cookie(Constants.Normal.TOKEN_NAME, null);
        cookie.setHttpOnly(true);
        cookie.setMaxAge(0);
        cookie.setPath("/");
        res.addCookie(cookie);
        return ResponseResult.success();
    }

    @ApiOperation(value = "注册", notes = "注册新用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "loginName", value = "登录名", required = true, dataTypeClass = String.class, paramType = "save", example = "admin"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataTypeClass = String.class, paramType = "save", example = "123456"),
            @ApiImplicitParam(name = "email", value = "邮箱", required = true, dataTypeClass = String.class, paramType = "save", example = "1234@163.com"),
    })
    @PostMapping("/register/action")
    @ResponseBody
    public ResponseResult registerAction(@Valid RegisterDTO registerDTO, BindingResult result) throws Exception {

        if (result.hasErrors()) {
            FieldError fieldError = result.getFieldError();
            return ResponseResult.failure(fieldError.getDefaultMessage());
        }
        // 获取aes密钥
        String afterDecryptionPassword = PasswordService.decryptAesPassword(registerDTO.getPassword(), Constants.Normal.PASSWORD_KEY);
        registerDTO.setPassword(afterDecryptionPassword);
        SystemUser user = new SystemUser();
        BeanUtils.copyProperties(registerDTO, user);
        systemUserService.registerUser(user);
        // 登录
        LoginDTO loginDTO = new LoginDTO();
        BeanUtils.copyProperties(registerDTO, loginDTO);
        systemUserService.login(loginDTO);
        return ResponseResult.success();
    }

}
